/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { GrpcObject, loadPackageDefinition,} from '.'
import { ProtoGrpcType } from './generated/channelz';
import { ChannelzClient } from './generated/grpc/channelz/v1/Channelz';
import { PackageDefinition } from './make-client';

interface SayHelloClient extends GrpcObject {
  path: GrpcObject,
  requestStream: GrpcObject,
  responseStream: GrpcObject,
  requestType: GrpcObject,
  responseType: GrpcObject,
  requestSerialize: GrpcObject,
  requestDeserialize: GrpcObject,
  responseSerialize: GrpcObject,
  responseDeserialize: GrpcObject,
}

interface GreeterClient extends GrpcObject {
  SayHello: SayHelloClient
}

interface HelloWordlClient extends GrpcObject {
  Greeter: GreeterClient
}

interface HellClient extends GrpcObject {
  helloworld: HelloWordlClient
  // HelloWordlClient = GrpcObject | ServiceClientConstructor | ProtobufTypeDefinition
}

export interface RpcMethod<RequestType, ResponseType> {
  SayHello:{
    path: string;
    requestStream: boolean;
    responseStream: boolean;
    requestType: Function;
    responseType: Function;
    requestSerialize: (arg: RequestType) => string;
    requestDeserialize: (arg: any) => RequestType;
    responseSerialize: (arg: ResponseType) => string;
    responseDeserialize: (arg: any) => ResponseType;
  }
}

export interface RpcService {
  [serviceName: string]: {
    [methodName: string]: RpcMethod<any, any>;
  };
}

// export function createServiceDefinition(json: RpcService){
//   const serviceDefinition:GrpcObject = loadPackageDefinition(json) as HellClient
//   console.info(`static_grpc_client serviceDefinition: ${JSON.stringify(serviceDefinition)} ${typeof(serviceDefinition)}`);
//   return serviceDefinition
// }
//
// export function createClient(json:RpcService,address:string){
//   const serviceDefinition:GrpcObject = createServiceDefinition(json)
//   const definition = serviceDefinition.helloworld as HelloWordlClient
//   const definition1 = definition.Greeter as GreeterClient
//   const definition2 = definition1 as unknown as Client
//   const client = new Client(address, ChannelCredentials.createInsecure())
//   return client
// }

interface HelloRequest {
  name: string;
}

interface HelloReply {
  message: string;
}

const HelloRequest: Function = (name: string) => {
  name = name;
};

const HelloReply: Function = (message: string) => {
  message = message;
};

export function createServiceDefinition(json: PackageDefinition){
  const serviceDefinition = loadPackageDefinition(json) as unknown as ProtoGrpcType;;
  console.info(`static_grpc_client serviceDefinition: ${JSON.stringify(serviceDefinition)} ${typeof(serviceDefinition)}`);
  return serviceDefinition
}

export function createClient(json:PackageDefinition,address:string){
  let channelzClient: ChannelzClient;
  let channelzGrpcObject = createServiceDefinition(json)
  // console.info(`createClient createServiceDefinition: ${JSON.stringify(channelzGrpcObject)} ${typeof(channelzGrpcObject)}`);
  console.info('createClient before try')
  try{
    console.info('createClient begin try')
    const text1 = channelzGrpcObject.grpc
    console.info(`createClient createServiceDefinition: ${JSON.stringify(channelzGrpcObject)} ${typeof(channelzGrpcObject)}`);
    console.info(`createClient createServiceDefinition: ${JSON.stringify(channelzGrpcObject.grpc)} ${typeof(channelzGrpcObject.grpc)}`);
    console.info(`createClient create catch err: ${text1}`);
    const text2 = channelzGrpcObject.grpc["channelz"]
    const text3 = channelzGrpcObject.grpc["channelz"]["v1"]
    const text4 = channelzGrpcObject.grpc["channelz"]["v1"]["Channelz"]
    console.info('createClient begin console')
    console.info(`createClient createServiceDefinition: ${JSON.stringify(channelzGrpcObject)} ${typeof(channelzGrpcObject)}`);
    console.info(`createClient createServiceDefinition: ${JSON.stringify(channelzGrpcObject.grpc)} ${typeof(channelzGrpcObject.grpc)}`);
    console.info(`createClient create catch err: ${text1}`);
    console.info(`createClient create catch err: ${text2}`);
    console.info(`createClient create catch err: ${text3}`);
    console.info(`createClient create catch err: ${text4}`);
    // channelzClient = new channelzGrpcObject.grpc["channelz"]["v1"]["Channelz"](
    //   address,
    //   ChannelCredentials.createInsecure()
    // )
  } catch (err) {
    console.info(`createClient create catch err: ${err.message}`);
  }
  console.info(`createClient create client: ${JSON.stringify(channelzClient)} ${typeof(channelzClient)}`);
  return channelzClient
}




